package jwanalytics.dbloader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Vector;

import jwanalytics.dbloader.DB;

import org.apache.log4j.Logger;


/** 
 * Delete some parts of the database. This class has a main method which will present a series of 7 command line
 * options for database delete/drop operations. 
 */
public class DeletePartsOfDatabase {
	
	/** Logger for all pages. */
	public static Logger logger = Logger.getLogger("jwanalytics");
	
	/** @TODO: make this list of tables a property list in the .properties file. Order is important for referencial integrity reasons. */
	public static Vector<String> tableList = new Vector<String>();
	
	/** 
	 * This list is used to delete table rows which are populated during runtime without deleting tables
	 * populated during deployment time (such as date_dimension). 
	 */
	public static Vector<String> runtimePopulatedTableList = new Vector();	
	
	/** List of sequences used for this database (drop statement is different than from tables). */
	public static Vector<String> sequenceList = new Vector();
	
	
	static {
		Props.init(Props.PROPS_FILE, false); //in case it was not initialized yet.
		try {
			tableList = DB.getAllTableNames(Props.PROPS_FILE);
			runtimePopulatedTableList = DB.getAllRuntimePopulatedTableNames(Props.PROPS_FILE);
		} catch(Exception e) {
			logger.error("WAERROR0050:"+e);
		}
		//@TODO make sequence list be a property in the properties file like above pattern.
		sequenceList.add("c_client_system_sequence");
		sequenceList.add("c_customer_sequence");
		sequenceList.add("c_page_sequence");
		sequenceList.add("c_page_fact_sequence");
		sequenceList.add("c_referer_sequence");
		sequenceList.add("c_returning_browser_sequence");
		sequenceList.add("c_session_sequence");		 
	};
	
	
	/** 
	 * Will present a menu with 7 options when executed:
	 * Choose an option:
	 * 1. Delete data from all tables (includes date dimension, etc).
	 * 2. Drop all tables (will not drop sequences).
	 * 3. Drop all sequences.
	 * 4. Execute all steps above.
	 * 5. Delete only tables populated during runtime.
	 * 6. Delete tables populated during runtime and recreate their sequences.
	 * 7. Exit. 
	 */
	public static void main(String[] args) {
		Props.init(Props.PROPS_FILE, false);
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String answer = null;
		while (true) {
			answer = null;
			// TODO Auto-generated method stub
			System.out.println("Choose an option:");
			System.out.println("1. Delete data from all tables (includes date dimension, etc).");
			System.out.println("2. Drop all tables (will not drop sequences).");
			System.out.println("3. Drop all sequences.");
			System.out.println("4. Execute all steps above.");
			System.out.println("5. Delete only tables populated during runtime.");			
			System.out.println("6. Delete tables populated during runtime and recreate their sequences.");						
			System.out.println("7. Exit.");			
			try {
				answer = br.readLine();
			} catch (IOException e) {
				logger.error("WAERROR0036:"+e);
				if (logger.isDebugEnabled()) e.printStackTrace();
			}
			System.out.println("Your answer was:"+answer);
			if (answer == null) continue;
			if (answer.toUpperCase().indexOf("1") != -1) {
				deleteTableList(tableList);
			} else if (answer.toUpperCase().indexOf("2") != -1) {
				dropTableList(tableList);
			} else if (answer.toUpperCase().indexOf("3") != -1) {
				dropSequenceList(sequenceList);
			} else if (answer.toUpperCase().indexOf("4") != -1) {
				deleteTableList(tableList);
				dropTableList(tableList);
				dropSequenceList(sequenceList);
			} else if (answer.toUpperCase().indexOf("5") != -1) {
				deleteTableList(runtimePopulatedTableList);
			} else if (answer.toUpperCase().indexOf("6") != -1) {
				deleteTableList(runtimePopulatedTableList);
				dropSequenceList(sequenceList);				
			} if (answer.toUpperCase().indexOf("7") != -1) {
				break;
			};
		}
	}
	
	
	/**
	 * Will delete every table of the list passed as a parameter. 
	 * @param tl: Table list to delete.
	 */ 
	public static void deleteTableList(Vector<String> tl) {
		StringBuffer sb = new StringBuffer("Deleted tables: ");
		Iterator<String> it = tl.iterator();
		String table = null;
		while (it.hasNext()) {
			table = it.next();
			try {
				
				DB.executeStatement("DELETE FROM "+table);
				sb.append(table+",");
			} catch (Exception e) {
				logger.info("Failed deleting table:"+table+", maybe it is already dropped.");
			}
		}
		sb.deleteCharAt(sb.length()-1);
		sb.append(".");
		logger.info(sb);
	}
	
	
	/**
	 * Will drop every table of the list passed as a parameter. 
	 * Drop all tables, but not sequences. 
	 */
	public static void dropTableList(Vector<String> tl) {
		StringBuffer sb = new StringBuffer("Dropped tables: ");
		Iterator<String> it = tl.iterator();
		String table = null;
		while (it.hasNext()) {
			table = it.next();
			try {
				DB.executeStatement("DROP TABLE "+table);
				sb.append(table+",");
			} catch (Exception e) {
				logger.info("Failed dropping table:"+table+", maybe it is already dropped.");
			}
		}
		sb.deleteCharAt(sb.length()-1);
		sb.append(".");
		logger.info(sb);		
	}
	
	
	/** Drop all sequences of the list passed as a parameter. */
	public static void dropSequenceList(Vector<String> sl) {
		StringBuffer sb = new StringBuffer("Dropped sequences: ");
		Iterator<String> it = sl.iterator();
		String sequence = null;
		while (it.hasNext()) {
			sequence = it.next();
			try {
				DB.executeStatement("DROP SEQUENCE "+sequence);
				sb.append(sequence+",");				
			} catch (Exception e) {
				logger.info("Failed dropping sequence:"+sequence+", maybe it is already dropped.");				
			}
		}
		sb.deleteCharAt(sb.length()-1);
		sb.append(".");
		logger.info(sb);		
	}	
	
	
}
